<template>
  <div class="reactivity-demo">
    <h1>🎮 Vue3 响应式基础闯关游戏 🎮</h1>
    
    <!-- 关卡导航 -->
    <div class="level-nav">
      <button 
        v-for="level in levels" 
        :key="level.id"
        @click="currentLevel = level.id"
        :class="{ active: currentLevel === level.id }"
      >
        关卡 {{ level.id }}
      </button>
    </div>

    <!-- 关卡 1: ref 示例 -->
    <div v-if="currentLevel === 1" class="level-content">
      <h2>🌟 关卡 1｜ref：让"原始值"变成"响应式小精灵"</h2>
      <p class="tip">把 ref 想象成"魔法存钱罐"：外面看是一个整体，里面实际藏着金币（.value）。你摇一摇（修改.value），页面就会发光（更新）。</p>
      
      <div class="game-container">
        <h3>勇者血量：{{ hp }}</h3>
        <div class="hp-bar">
          <div class="hp-fill" :style="{ width: hp + '%' }"></div>
        </div>
        <button @click="attack" :disabled="attacking" class="btn-attack">
          {{ attacking ? '攻击中...' : '发起攻击' }}
        </button>
      </div>
    </div>

    <!-- 关卡 2: reactive 示例 -->
    <div v-if="currentLevel === 2" class="level-content">
      <h2>🌟 关卡 2｜reactive：让"对象"一次响应到底</h2>
      <p class="tip">reactive 像"响应式大别墅"：门牌号是整栋别墅，拆走一块砖（解构）就失去魔法。</p>
      
      <div class="hero-container">
        <h3>{{ name }} Lv.{{ level }}</h3>
        <p>技能列表：{{ hero.skills.join('、') }}</p>
        <button @click="levelUp" class="btn-level">打怪升级</button>
      </div>
    </div>

    <!-- 关卡 3: computed 示例 -->
    <div v-if="currentLevel === 3" class="level-content">
      <h2>🌟 关卡 3｜computed：声明式"衍生数据"</h2>
      <p class="tip">computed 像"自动奶茶机"：你放原料（ref/reactive），它自动出奶茶（计算结果），原料不变奶茶不重新做。</p>
      
      <div class="cart-container">
        <div class="cart-item">
          <p>单价：{{ price }} 元</p>
          <p>数量：{{ quantity }} 杯</p>
          <p>折扣：{{ discount * 10 }} 折</p>
        </div>
        <h4>应付：{{ total.toFixed(2) }} 元</h4>
        <button @click="add" class="btn-add">再来一杯</button>
      </div>
    </div>

    <!-- 关卡 4: watch & watchEffect 示例 -->
    <div v-if="currentLevel === 4" class="level-content">
      <h2>🌟 关卡 4｜watch & watchEffect：侧效应"侦察兵"</h2>
      <p class="tip">watch 是"定点监控摄像头"；watchEffect 是"AI 巡检无人机"，飞一圈看到啥就记录啥。</p>
      
      <!-- watch 示例 -->
      <div class="watch-container">
        <h3>👁️ watch 示例</h3>
        <p>当前 ID: {{ id }}</p>
        <button @click="id++" class="btn-id">增加 ID</button>
        <div v-if="data" class="data-display">
          <p>加载的数据: {{ data.title }}</p>
          <p>状态: {{ data.completed ? '已完成' : '未完成' }}</p>
        </div>
      </div>

      <!-- watchEffect 示例 -->
      <div class="watch-effect-container">
        <h3>🚁 watchEffect 示例</h3>
        <p>角色坐标：({{ x }}, {{ y }})</p>
        <button @click="moveRandomly" class="btn-move">随机移动</button>
        <p class="console-tip">打开控制台查看效果</p>
      </div>
    </div>

    <!-- 关卡 5: TypeScript 集成示例 -->
    <div v-if="currentLevel === 5" class="level-content">
      <h2>🌟 关卡 5｜script setup + 类型推断：TS 丝滑连招</h2>
      
      <div class="ts-container">
        <div class="ts-demo">
          <h3>泛型 ref 示例</h3>
          <p>分数: {{ score }}</p>
          <button @click="score++" class="btn-score">加分</button>
          <p class="code-hint">const score = ref<number>(98) // 类型安全！</p>
        </div>
        
        <div class="ts-demo">
          <h3>接口示例</h3>
          <p>用户: {{ user.name }}</p>
          <p>年龄: {{ user.age }}</p>
          <p class="code-hint">interface User { name: string; age: number; }</p>
        </div>
      </div>
    </div>

    <!-- 关卡 6: 常见问题 -->
    <div v-if="currentLevel === 6" class="level-content">
      <h2>🌟 关卡 6｜常见掉坑题（趣味抢答）</h2>
      
      <div class="qa-container">
        <div class="qa-item">
          <h3>Q1 为什么 const { count } = ref(0) 丢失响应？</h3>
          <p>A: 解构的是基本值，脱离 ref 包裹；正确用 const { count } = toRefs(reactive({ count: 0 }))。</p>
        </div>
        
        <div class="qa-item">
          <h3>Q2 直接给 reactive 数组 push 新对象，会响应吗？</h3>
          <p>A: 会！reactive 数组方法被代理，放心 push。</p>
        </div>
        
        <div class="qa-item">
          <h3>Q3 在定时器里修改 ref，视图会更新吗？</h3>
          <p>A: 会！Vue3 代理不受"异步限制"困扰，无需 $nextTick。</p>
        </div>
      </div>
    </div>

    <!-- 关卡 7: 小作业 -->
    <div v-if="currentLevel === 7" class="level-content">
      <h2>🌟 关卡 7｜综合练习</h2>
      
      <!-- 温度转换器 -->
      <div class="exercise-container">
        <h3>🌡️ 摄氏 ↔ 华氏转换器</h3>
        <div class="temp-converter">
          <input v-model.number="celsius" type="number" placeholder="摄氏度">
          <span>↔</span>
          <input v-model.number="fahrenheit" type="number" placeholder="华氏度">
        </div>
      </div>

      <!-- 待办列表 -->
      <div class="exercise-container">
        <h3>📝 待办列表</h3>
        <div class="todo-app">
          <input v-model="newTodo" @keyup.enter="addTodo" placeholder="添加待办...">
          <button @click="addTodo" class="btn-add-todo">添加</button>
          
          <ul class="todo-list">
            <li v-for="(todo, index) in todos" :key="index">
              <input type="checkbox" v-model="todo.completed">
              <span :class="{ completed: todo.completed }">{{ todo.text }}</span>
              <button @click="removeTodo(index)" class="btn-remove">删除</button>
            </li>
          </ul>
          
          <p>剩余: {{ remainingTodos }} 项</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, watchEffect, toRefs, onMounted, onUnmounted } from 'vue'

// 关卡导航
const currentLevel = ref(1)
const levels = [
  { id: 1, name: 'ref 基础' },
  { id: 2, name: 'reactive 基础' },
  { id: 3, name: 'computed 计算属性' },
  { id: 4, name: 'watch 监听' },
  { id: 5, name: 'TypeScript 集成' },
  { id: 6, name: '常见问题' },
  { id: 7, name: '综合练习' }
]

// 关卡 1: ref 示例
const hp = ref(100)          // 英雄血量
const attacking = ref(false) // 是否正在攻击

const attack = () => {
  attacking.value = true
  setTimeout(() => {
    hp.value -= 20
    attacking.value = false
  }, 500)
}

// 关卡 2: reactive 示例
interface Hero {
  name: string
  level: number
  skills: string[]
}

const hero = reactive<Hero>({
  name: 'Vue 法师',
  level: 1,
  skills: ['火球术']
})

const { name, level } = toRefs(hero)

const levelUp = () => {
  level.value++
  if (level.value === 3) hero.skills.push('冰冻术')
  if (level.value === 5) hero.skills.push('雷电术')
}

// 关卡 3: computed 示例
const price = ref(25)
const quantity = ref(2)
const discount = ref(0.8)

// 计算购物车总价
const total = computed<number>(() => {
  return price.value * quantity.value * discount.value
})

const add = () => quantity.value++

// 关卡 4: watch & watchEffect 示例
const id = ref(1)
const data = ref<any>(null)

// 监听 id 变化，拉取新数据
watch(id, async (newId, oldId) => {
  console.log(`ID 从 ${oldId} → ${newId}`)
  try {
    const res = await fetch(`https://jsonplaceholder.typicode.com/todos/${newId}`)
    data.value = await res.json()
  } catch (error) {
    console.error('获取数据失败:', error)
  }
}, { immediate: true })

const x = ref(0)
const y = ref(0)

// 只要 x 或 y 变，就打印最新坐标
watchEffect(() => {
  console.log(`角色坐标：(${x.value}, ${y.value})`)
})

const moveRandomly = () => {
  x.value = Math.floor(Math.random() * 100)
  y.value = Math.floor(Math.random() * 100)
}

// 关卡 5: TypeScript 示例
const score = ref<number>(98) // 类型安全的 ref

interface User {
  name: string
  age: number
}

const user = ref<User>({
  name: 'Vue 学习者',
  age: 25
})

// 关卡 7: 综合练习

// 温度转换器
const celsius = ref<number>(0)
const fahrenheit = computed<number>({
  get: () => celsius.value * 9/5 + 32,
  set: (value) => {
    celsius.value = (value - 32) * 5/9
  }
})

// 待办列表
interface Todo {
  text: string
  completed: boolean
}

const newTodo = ref('')
const todos = ref<Todo[]>([
  { text: '学习 Vue 3 响应式', completed: false },
  { text: '掌握 ref 和 reactive', completed: false }
])

const remainingTodos = computed(() => {
  return todos.value.filter(todo => !todo.completed).length
})

const addTodo = () => {
  if (newTodo.value.trim()) {
    todos.value.push({
      text: newTodo.value,
      completed: false
    })
    newTodo.value = ''
  }
}

const removeTodo = (index: number) => {
  todos.value.splice(index, 1)
}

// 鼠标位置监听演示
const handleMouseMove = (event: MouseEvent) => {
  x.value = event.clientX
  y.value = event.clientY
}

onMounted(() => {
  window.addEventListener('mousemove', handleMouseMove)
})

onUnmounted(() => {
  window.removeEventListener('mousemove', handleMouseMove)
})
</script>

<style scoped>
.reactivity-demo {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  font-family: 'Arial', sans-serif;
  background-color: #f5f5f5;
  min-height: 100vh;
}

h1 {
  text-align: center;
  color: #42b883;
  margin-bottom: 30px;
}

.level-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 30px;
  justify-content: center;
}

.level-nav button {
  padding: 10px 20px;
  background-color: #fff;
  border: 2px solid #e0e0e0;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.level-nav button:hover {
  border-color: #42b883;
}

.level-nav button.active {
  background-color: #42b883;
  color: white;
  border-color: #42b883;
}

.level-content {
  background-color: white;
  border-radius: 10px;
  padding: 30px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

h2 {
  color: #333;
  border-bottom: 2px solid #42b883;
  padding-bottom: 10px;
  margin-bottom: 20px;
}

.tip {
  background-color: #e6f7f0;
  padding: 15px;
  border-left: 4px solid #42b883;
  margin-bottom: 20px;
  color: #2c5e4c;
}

/* 关卡 1 样式 */
.game-container {
  text-align: center;
  padding: 20px;
}

.hp-bar {
  width: 100%;
  height: 30px;
  background-color: #e0e0e0;
  border-radius: 15px;
  overflow: hidden;
  margin: 20px 0;
}

.hp-fill {
  height: 100%;
  background-color: #42b883;
  transition: width 0.5s ease;
}

.btn-attack {
  padding: 10px 30px;
  background-color: #ff6b6b;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.3s;
}

.btn-attack:hover:not(:disabled) {
  background-color: #ee5253;
}

.btn-attack:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

/* 关卡 2 样式 */
.hero-container {
  text-align: center;
  padding: 20px;
  background-color: #f0f8ff;
  border-radius: 10px;
}

.btn-level {
  padding: 10px 30px;
  background-color: #4285f4;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.3s;
}

.btn-level:hover {
  background-color: #3367d6;
}

/* 关卡 3 样式 */
.cart-container {
  padding: 20px;
  background-color: #fff8e1;
  border-radius: 10px;
}

.cart-item {
  margin-bottom: 20px;
}

.btn-add {
  padding: 10px 30px;
  background-color: #ffa726;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.3s;
}

.btn-add:hover {
  background-color: #fb8c00;
}

/* 关卡 4 样式 */
.watch-container,
.watch-effect-container {
  margin-bottom: 30px;
  padding: 20px;
  background-color: #f3e5f5;
  border-radius: 10px;
}

.btn-id,
.btn-move {
  padding: 8px 20px;
  background-color: #9c27b0;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.btn-id:hover,
.btn-move:hover {
  background-color: #7b1fa2;
}

.data-display {
  margin-top: 20px;
  padding: 15px;
  background-color: white;
  border-radius: 5px;
}

.console-tip {
  color: #666;
  font-style: italic;
  margin-top: 10px;
}

/* 关卡 5 样式 */
.ts-container {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
}

.ts-demo {
  flex: 1;
  min-width: 250px;
  padding: 20px;
  background-color: #e3f2fd;
  border-radius: 10px;
}

.btn-score {
  padding: 8px 20px;
  background-color: #2196f3;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.btn-score:hover {
  background-color: #1976d2;
}

.code-hint {
  background-color: #f5f5f5;
  padding: 10px;
  border-radius: 5px;
  font-family: monospace;
  font-size: 14px;
  margin-top: 10px;
  color: #666;
}

/* 关卡 6 样式 */
.qa-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.qa-item {
  padding: 20px;
  background-color: #f1f8e9;
  border-radius: 10px;
}

.qa-item h3 {
  color: #558b2f;
  margin-top: 0;
}

/* 关卡 7 样式 */
.exercise-container {
  margin-bottom: 30px;
  padding: 20px;
  background-color: #e8f5e9;
  border-radius: 10px;
}

.temp-converter {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: 20px;
}

.temp-converter input {
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 5px;
  width: 120px;
}

.todo-app {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.todo-app input[type="text"] {
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 5px;
  flex: 1;
}

.btn-add-todo {
  padding: 10px 20px;
  background-color: #4caf50;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

.todo-list {
  list-style: none;
  padding: 0;
}

.todo-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  background-color: white;
  border-radius: 5px;
  margin-bottom: 5px;
}

.todo-list li .completed {
  text-decoration: line-through;
  color: #888;
}

.btn-remove {
  margin-left: auto;
  padding: 5px 10px;
  background-color: #ff5722;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

@media (max-width: 768px) {
  .ts-container {
    flex-direction: column;
  }
  
  .temp-converter {
    flex-direction: column;
  }
}
</style>